﻿Imports System.Reflection
Imports System.Collections.Specialized
Imports System.Collections.ObjectModel
Imports Kairyu.Load
Imports System.Threading.Tasks

''' <summary>
''' コレクション初期化
''' </summary>
''' <remarks>
''' #102 LazyListをObservableCollection型継承に変える
''' </remarks>
Public Class CollectionInitializer

#Region "Init"
    ''' <summary>
    ''' コレクションプロパティを初期化します。既存アイテムは破棄されます
    ''' </summary>
    Public Shared Function Init(Of T)(instance As T) As T
        Dim q As IEnumerable(Of ChildRelation) = (From el In instance.GetType.ToTable.ChildRelations)
        Return Init(instance, q)
    End Function

    ''' <summary>
    ''' 該当プロパティのインスタンスを生成します。既存アイテムは破棄されます
    ''' </summary>
    Public Shared Function Init(Of T)(instance As T, childProp As PropertyInfo) As T
        Dim q As IEnumerable(Of ChildRelation) = (From el In instance.GetType.ToTable.ChildRelations Where el.CollectionProperty.Equals(childProp))
        Return Init(instance, q)
    End Function

    ''' <summary>
    ''' 該当プロパティのインスタンスを生成します。既存アイテムは破棄されます
    ''' </summary>
    Public Shared Function Init(Of T, ChildT)(instance As T) As T
        Dim q As IEnumerable(Of ChildRelation) = (From el In instance.GetType.ToTable.ChildRelations Where el.CollectionProperty.PropertyType.GetGenericArguments.First.Equals(GetType(ChildT)))
        Return Init(instance, q)
    End Function

    Private Shared Function Init(Of T)(instance As T, rels As IEnumerable(Of ChildRelation)) As T
        For Each rel As ChildRelation In rels
            Dim lst As IList = (New ObservableCollectionFactory).Create(instance, rel)
            rel.CollectionProperty.SetValue(instance, lst, Nothing)
        Next
        Return instance
    End Function

#End Region

#Region "InitAsLazy"
    ''' <summary>
    ''' コレクションプロパティをLazyListで初期化します
    ''' </summary>
    Friend Shared Function InitAsLasy(Of T, ChildT)(instance As T, rels As IEnumerable(Of ChildRelation), loadQuery As Query(Of ChildT)) As T
        '#104 子結合条件が複数の場合、Fetchができない
        Dim lst As LazyList(Of ChildT) = (New LazyListFactory).Create(Of ChildT)(instance, rels, loadQuery)
        rels.First.CollectionProperty.SetValue(instance, lst, Nothing)
        Return instance
    End Function
#End Region

End Class